package com.nodecollege.cloud.service.impl;

import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.exception.UpmsException;
import com.nodecollege.cloud.common.model.BindVO;
import com.nodecollege.cloud.common.model.QueryVO;
import com.nodecollege.cloud.common.model.po.UpmsApp;
import com.nodecollege.cloud.common.model.po.UpmsTenant;
import com.nodecollege.cloud.common.model.po.UpmsTenantApp;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.common.utils.RedisUtils;
import com.nodecollege.cloud.dao.mapper.UpmsTenantAppMapper;
import com.nodecollege.cloud.service.AppService;
import com.nodecollege.cloud.service.TenantAppService;
import com.nodecollege.cloud.service.TenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * 租户应用
 *
 * @author LC
 * @date 2019/12/21 23:29
 */
@Service
public class TenantAppServiceImpl implements TenantAppService {

    @Autowired
    private TenantService tenantService;

    @Autowired
    private AppService appService;

    @Autowired
    private UpmsTenantAppMapper upmsTenantAppMapper;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 获取租户应用列表缓存
     *
     * @param tenantId
     * @return
     */
    @Override
    public List<UpmsTenantApp> getTenantAppListCache(Long tenantId) {
        List<UpmsTenantApp> list = redisUtils.getList("upms:tenantAppList:" + tenantId, UpmsTenantApp.class);
        if (list != null) {
            return list;
        }
        BindVO query = new BindVO();
        query.setSourceIds(Arrays.asList(tenantId));
        list = upmsTenantAppMapper.selectList(query);
        List<UpmsApp> appList = appService.getAppListCache();
        for (int i = 0; i < list.size(); i++) {
            Iterator<UpmsApp> iterator = appList.iterator();
            while (iterator.hasNext()) {
                UpmsApp upmsApp = iterator.next();
                if (list.get(i).getAppId().equals(upmsApp.getAppId())) {
                    list.get(i).setAppCode(upmsApp.getAppCode());
                    list.get(i).setAppName(upmsApp.getAppName());
                    list.get(i).setAppType(upmsApp.getAppType());
                    list.get(i).setNum(upmsApp.getNum());
                    // 应用被冻结，则租户应用关系也冻结
                    if (NCConstants.INT_2.equals(upmsApp.getState())
                            || NCConstants.INT_NEGATIVE_1.equals(upmsApp.getState())) {
                        list.get(i).setState(upmsApp.getState());
                    }
                    iterator.remove();
                    break;
                }
            }
        }
        redisUtils.set("upms:tenantAppList:" + tenantId, list, 24 * 60 * 60);
        return list;
    }

    /**
     * 清除租户应用列表缓存
     *
     * @param tenantId
     */
    @Override
    public void clearTenantAppListCache(Long tenantId) {
        if (tenantId != null) {
            redisUtils.delete("upms:tenantAppList:" + tenantId);
        } else {
            redisUtils.delete(redisUtils.keys("upms:tenantAppList:*"));
        }
    }

    /**
     * 绑定租户应用
     *
     * @param bindVO
     */
    @Override
    public void bindTenantApp(BindVO bindVO) {
        if ((bindVO.getSourceAll() && bindVO.getTargetAll())
                || (NCUtils.isNullOrEmpty(bindVO.getSourceIds()) && NCUtils.isNullOrEmpty(bindVO.getTargetIds()))) {
            throw new UpmsException("-1", "绑定入参有误！");
        }
        // 查询租户信息
        List<UpmsTenant> sourceList = new ArrayList<>();
        QueryVO queryVO = new QueryVO();
        // 查询所有
        queryVO.setPageSize(NCConstants.INT_NEGATIVE_1);
        if (!bindVO.getSourceAll()) {
            queryVO.setLongList(bindVO.getSourceIds());
        }
        sourceList = tenantService.getTenantList(queryVO).getRows();

        // 查询应用信息
        List<UpmsApp> targetList = new ArrayList<>();

        List<UpmsApp> appList = appService.getAppListCache();
        if (!bindVO.getTargetAll()) {
            for (int i = 0; i < appList.size(); i++) {
                Iterator<Long> iterator = bindVO.getTargetIds().iterator();
                while (iterator.hasNext()) {
                    Long id = iterator.next();
                    if (id.equals(appList.get(i).getAppId())) {
                        targetList.add(appList.get(i));
                        iterator.remove();
                        break;
                    }
                }
            }
        } else {
            bindVO.setTargetIds(new ArrayList<>(appList.size()));
            for (int i = 0; i < appList.size(); i++) {
                bindVO.getTargetIds().add(appList.get(i).getAppId());
            }
        }
        // 查询已关联的数据
        List<UpmsTenantApp> exList = upmsTenantAppMapper.selectList(bindVO);

        // 构造未关联的数据
        List<UpmsTenantApp> nonExList = new ArrayList<>();
        for (int i = 0; i < sourceList.size(); i++) {
            for (int j = 0; j < targetList.size(); j++) {
                boolean ex = false;
                Iterator<UpmsTenantApp> iterator = exList.iterator();
                while (iterator.hasNext()) {
                    UpmsTenantApp app = iterator.next();
                    if (sourceList.get(i).getTenantId().equals(app.getTenantId())
                            && targetList.get(j).getAppId().equals(app.getAppId())) {
                        ex = true;
                        iterator.remove();
                        break;
                    }
                }
                if (!ex) {
                    UpmsTenantApp non = new UpmsTenantApp();
                    non.setTenantId(sourceList.get(i).getTenantId());
                    non.setAppId(targetList.get(j).getAppId());
                    non.setState(NCConstants.INT_1);
                    nonExList.add(non);
                }
            }
        }

        // 批量进行保存
        for (int i = 0; i < nonExList.size(); i++) {
            upmsTenantAppMapper.insert(nonExList.get(i));
        }
        clearTenantAppListCache(null);
    }

    /**
     * 更新租户应用状态
     *
     * @param bindVO
     */
    @Override
    public void updateTenantAppState(BindVO bindVO) {
        NCUtils.nullOrEmptyThrow(bindVO.getSourceIds(), new UpmsException("-1", "绑定入参有误！"));
        NCUtils.nullOrEmptyThrow(bindVO.getState(), new UpmsException("-1", "锁定/解锁入参有误！"));

        // 批量进行更新
        bindVO.getSourceIds().forEach(item -> {
            UpmsTenantApp updateApp = new UpmsTenantApp();
            updateApp.setTenantAppId(item);
            updateApp.setState(bindVO.getState());
            upmsTenantAppMapper.updateByPrimaryKeySelective(updateApp);
        });
        clearTenantAppListCache(null);
    }
}
